﻿#define  _CRT_SECURE_NO_WARNINGS 1
//如何定义二维数组呢？
// type arr_name[常量值1][常量值2]； type-类型  arr_name-数组名   常量值1-行 常量值1-列
#include <stdio.h>
//int main()
//{
//	int data[3][5]; //这个数组叫data  整型  3行5列
//	float score[5][30];
//	int data[3][5] = { 1,2,3,4,5,6,7,8 };//不完全初始化   后面的会默认为0
//	float score[5][30] = { 0.0 }; //不完全初始化  会是全0
//	int  data2[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };//完全初始化
//	//还有可以按照行进行初始化
//	int data3[3][5] = { {1,2},{3.4},{5,6} };//12第一行 34第二行 56第三行  第一行 第二行 第三行剩下的都是0
//	//初始化的时候行可以省略但是列不可以省略
//	int data5[3][] = { 1,2,3,4 };//这样就错
//	int data6[][5] = { 1,2,3,4 };//这样可以  编译器会自动根据元素个数计算行
//	int data7[][] = { 1,2,3,4 };//这样就不行了
//
//	int data8[][5] = { 1,2,3,4,5,6,7,8 }; //两行
//	int data9[][5] = { {1,2},{3,4},{5,6} };//这有三行  因为这三个一维数组分别放在三行
//	return 0;
//
//}
//二维数组的使用，二维数组也有下标，分为行下标和列下标，也是从0开始
//int main()
//{
//	//int arr[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };
//	////arr[1][2];//这样就定位到第二行 第三列  1.2是他对应的下标
//	//printf("%d\n", arr[1][2]); //这样打印出来的就是4
//	//printf("%d\n", arr[2][4]);//这样打印出来的就是7 定位到了第三行 第五列
//	//如何给二维数组 输入值并且打印出来
//	int arr1[3][5] = { 0 };
//	//输入值
//	int i = 0;
//	for (i = 0; i < 3; i++)  //这样在这个循环中i就能表示012，也就是arr1这个二维数组对应的 行的下标
//	{
//		int j = 0;  //这个时候再嵌套一个for循环去在该行中去表示列对于的下标01234
//		for (j = 0; j < 5; j++)
//		{
//			scanf("%d", &arr1[i][j]);//这是数组的一个元素需要取地址，数组名才是地址，数组的一个元素不是地址
//
//		}
//	}
//	//输出
//	for (i = 0; i < 3; i++)
//	{
//		int j = 0;
//		for (j = 0; j < 5; j++)
//		{
//			printf("%d ", arr1[i][j]);
//		}
//		printf("\n");//打印完一行之后换行
//	}
//
//
//	return 0;
//}

//二维数组在内存中的存储
//int main()
//{
//	int arr[3][5] = { 0 };
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		int j = 0;
//		for (j = 0; j < 5; j++)
//		{
//			printf("&arr[%d][%d] = %p\n",i,j, &arr[i][j]); //%p打印地址 发现还是一样差4个比特（一个整型元素）
//			//所以二维数组在内存中的存储也是连续存放的
//			}
//	}
//	return 0;
//}

//刚才我们都是一行一行的打印，现在我们一列一列的打印

//int main()
//{
//	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		int j = 0;
//		for (j = 0; j < 3; j++)
//		{
//			printf("%d ", arr[j][i]);
//		}
//		printf("\n");
//	} 
//	return 0;
//}

//int main()
//{
//	int arr[10];
//	int n = 10;
//	int arr[n]; //给不了变量，在c语言的c99标准之前，数组在创建的时候，数组大小的指定只能使用常量
//	//在c99之后c语言引入了变长数组的概念，使得数组的大小可以使用变量来决定
//	return 0;
//}
//
//99中给⼀个变⻓数组（variable - length array，简称 VLA）的新特性，允许我们可以使⽤变量指定
// 变长数组不可以初始化噢
//数组⼤⼩。
//请看下⾯的代码：
//int n = a + b;
//int arr[n]
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int arr[n];
//	return 0;
//}  //但是vs2022不支持变长数组，devc++/小熊猫c++底层使用gcc，gcc支持c99的变长数组

//数组练习
//1.多个字符从两端移动，向中间汇聚
#include <string.h>
#include <windows.h> 睡眠函数Sleep所需要的头文件
#include <stdlib.h> system用来执行系统命令的头文件
//int main()
//{
//	char arr1[] = "hello bit!!!!!!!!!"; //[hello bit!!!!!!!!!\0]
//	            // 0   去找最后一个！的下标
//	char arr2[] = "##################";
//	int left = 0;
//	int right = strlen(arr1)-1;  //strlen 字符长度  -1（\0）所占的 然后就可以得字符中最后一个的下标了
//
//	//arr2[left] = arr1[left]; //就是把arr1 最左边下标对应的东西换给arr2最左边下标对应的东西
//	//arr2[right] = arr1[right];//就是把arr1 最右边下标对应的东西换给arr2最右边下标对应的东西
//	//printf("%s\n", arr2);//这样就完成了一组的替换
//	//left++;
//	//right++;  所以其实这就是一个循环
//	while (left<=right)//小于的时候中间一定有元素，所以就继续，等于的时候就找到最中间的元素
//	{
//		arr2[left] = arr1[left]; //就是把arr1 最左边下标对应的东西换给arr2最左边下标对应的东西
//		arr2[right] = arr1[right];//就是把arr1 最右边下标对应的东西换给arr2最右边下标对应的东西
//		printf("%s\n", arr2);//这样就完成了一组的替换
//		Sleep(1000);//休眠1000毫秒  睡眠函数
//		system("cls");//清理控制台屏幕的信息
//		left++;
//		right--;
//	}printf("%s\n", arr2); //因为上面最清理了，所以再打印一次最后控制台屏幕显示的信息就可以了
//		return 0;
//}

//2.二分查找
//在⼀个升序的数组中查找指定的数字n，很容易想到的⽅法就是遍历数组，但是这种⽅法效率⽐较低。
//⽐如我买了⼀双鞋，你好奇问我多少钱，我说不超过300元。你还是好奇，你想知道到底多少，我就让
//你猜，你会怎么猜？你会1，2，3，4...这样猜吗？显然很慢；⼀般你都会猜中间数字，⽐如：150，然
//后看⼤了还是⼩了，这就是⼆分查找，也叫折半查找。